package chooongg.base.widget.hText

import android.graphics.Canvas
import android.graphics.Paint
import android.text.TextPaint
import android.util.AttributeSet
import android.view.ViewTreeObserver.OnGlobalLayoutListener
import androidx.core.view.ViewCompat
import java.util.*

/**
 * abstract class
 * Created by hanks on 15-12-19.
 */
abstract class HText : IHText {

    internal var mHeight = 0
    internal var mWidth = 0
    internal var mText: CharSequence? = null
    internal var mOldText: CharSequence? = null
    internal var mPaint: TextPaint? = null
    internal var mOldPaint: TextPaint? = null
    internal var mHTextView: HTextView? = null
    internal var gapList: MutableList<Float> = ArrayList()
    internal var oldGapList: MutableList<Float> = ArrayList()

    // 0 ~ 1 = 0f
    internal var progress: Float = 0f
        set(value) {
            field = value
            mHTextView!!.invalidate()
        }
    internal var mTextSize = 0f
    internal var oldStartX = 0f

    internal var listener: AnimationListener? = null
        private set

    override fun init(
        hTextView: HTextView?,
        attrs: AttributeSet?,
        defStyle: Int
    ) {
        mHTextView = hTextView
        mOldText = ""
        mText = hTextView!!.text
        progress = 1f
        mPaint = TextPaint(Paint.ANTI_ALIAS_FLAG)
        mOldPaint = TextPaint(mPaint)
        mHTextView!!.viewTreeObserver.addOnGlobalLayoutListener(object : OnGlobalLayoutListener {
            override fun onGlobalLayout() {
                mHTextView!!.viewTreeObserver.removeOnGlobalLayoutListener(this)
                mTextSize = mHTextView!!.textSize
                mWidth = mHTextView!!.width
                mHeight = mHTextView!!.height
                oldStartX = 0f
                try {
                    val layoutDirection =
                        ViewCompat.getLayoutDirection(mHTextView!!)
                    oldStartX =
                        if (layoutDirection == ViewCompat.LAYOUT_DIRECTION_LTR) mHTextView!!.layout
                            .getLineLeft(0) else mHTextView!!.layout.getLineRight(0)
                } catch (e: Exception) {
                    e.printStackTrace()
                }
                initVariables()
            }
        })
        prepareAnimate()
    }

    private fun prepareAnimate() {
        mTextSize = mHTextView!!.textSize
        mPaint!!.textSize = mTextSize
        mPaint!!.color = mHTextView!!.currentTextColor
        mPaint!!.typeface = mHTextView!!.typeface
        gapList.clear()
        for (element in mText!!) {
            gapList.add(mPaint!!.measureText(element.toString()))
        }
        mOldPaint!!.textSize = mTextSize
        mOldPaint!!.color = mHTextView!!.currentTextColor
        mOldPaint!!.typeface = mHTextView!!.typeface
        oldGapList.clear()
        for (element in mOldText!!) {
            oldGapList.add(mOldPaint!!.measureText(element.toString()))
        }
    }

    override fun animateText(text: CharSequence?) {
        mHTextView!!.text = text
        mOldText = mText
        mText = text
        prepareAnimate()
        animatePrepare(text)
        animateStart(text)
    }

    override fun onDraw(canvas: Canvas?) {
        drawFrame(canvas)
    }

    override fun setAnimationListener(listener: AnimationListener?) {
        this.listener = listener
    }

    protected abstract fun initVariables()
    protected abstract fun animateStart(text: CharSequence?)
    protected abstract fun animatePrepare(text: CharSequence?)
    protected abstract fun drawFrame(canvas: Canvas?)
}